package net.organizer.ui.actionhandler;

import java.util.List;
import java.util.logging.Logger;

import javax.servlet.http.HttpServletRequest;

import net.organizer.dao.Domain;
import net.organizer.dao.Person;
import net.organizer.ui.actionhandler.message.DuplicateFieldMessage;
import net.organizer.ui.actionhandler.message.OptimisticConcurrencyConflictMessage;
import net.organizer.ui.actionhandler.message.UnknownEntityMessage;

import org.json.JSONObject;

import com.googlecode.objectify.NotFoundException;
import com.googlecode.objectify.Objectify;
import com.googlecode.objectify.ObjectifyService;

public class PersonPutUpdateActionHandler extends ActionHandlerBase {
	private static final Logger logger = Logger.getLogger(PersonPutUpdateActionHandler.class.getName());
	
	@Override
	public void handleAction(HttpServletRequest req, JSONObject respJSONObject) throws Exception {
		logger.fine("handleAction");
		Objectify ofy = ObjectifyService.beginTransaction();
		long id = getParamValueAsLong(req, "id", true);
		logger.fine("handleAction... id: " + id);
		
		String fullTest = getParamValueAsString(req, "full", false);
		logger.fine("fullTest: " + fullTest);
		
		Domain domain = new Domain();
		domain.setName("domain1");
		try{
			Person person = ofy.get(Person.getKey(domain, id));
			Long version = getParamValueAsLong(req, "version", true);
			if(!person.getVersion().equals(version)){
				new OptimisticConcurrencyConflictMessage(id, respJSONObject);
				respJSONObject.put("person", person.toJSONObject());
				return;
			}
			person.setId(id);
			person.setDomainKey(domain.getKey());	
			
			person.setFirstName(getParamValueAsString(req, "firstName", true));
			person.setLastName(getParamValueAsString(req, "lastName", true));
			person.setGoogleUserId(getParamValueAsString(req, "googleUserId", true));

			person.setVersion(version + 1);
			if(fullTest != null){
				logger.fine("fullTest is not null, load detail fields");
				person.setPhoneNumberCell(getParamValueAsString(req, "phoneNumberCell", false));
				person.setPhoneNumberHome(getParamValueAsString(req, "phoneNumberHome", false));
				person.setPhoneNumberOffice(getParamValueAsString(req, "phoneNumberOffice", false));
				person.setDateOfBirth(getParamValueAsLong(req, "dateOfBirth", true));
			}
			logger.fine(String.format("person after applying http params: %s", person));
			
			List<Person> testPersons = ofy.query(Person.class).ancestor(domain.getKey()).filter("googleUserId = ", person.getGoogleUserId()).list();
			logger.fine(String.format("have %d oldPersons", testPersons.size()));
			if(testPersons.size() == 1){
				if(testPersons.get(0).getId().equals(person.getId())){
					// have found the instance being updated... no problem
				}else{
					new DuplicateFieldMessage("googleUserId", respJSONObject);
					respJSONObject.put("person", person.toJSONObject());
					return;
				}
			}
			ofy.put(person);
			ofy.getTxn().commit();
			respJSONObject.put("person", person.toJSONObject());
		}catch(NotFoundException e){
			new UnknownEntityMessage(id, respJSONObject);
		}finally{
			if(ofy.getTxn().isActive()){
				ofy.getTxn().rollback();
			}
		}
	}
}
